The exception recovery mechanism for the uninitialized_* algorithms did not work for iterators into discontiguous memory. git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@147343 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/include/algorithm b/include/algorithm index 4679845..f9c6843 100644 --- a/include/algorithm +++ b/include/algorithm
@@ -4751,6 +4751,8 @@ while (true) { __restart: + if (__nth == __last) + return; difference_type __len = __last - __first; switch (__len) {
diff --git a/include/memory b/include/memory index 565aa7d..d15d81a 100644 --- a/include/memory +++ b/include/memory
@@ -3215,12 +3215,23 @@ _ForwardIterator uninitialized_copy(_InputIterator __f, _InputIterator __l, _ForwardIterator __r) { - __destruct_n __d(0); typedef typename iterator_traits<_ForwardIterator>::value_type value_type; - unique_ptr<value_type, __destruct_n&> __h(&*__r, __d); - for (; __f != __l; ++__f, ++__r, __d.__incr((value_type*)0)) - ::new(&*__r) value_type(*__f); - __h.release(); +#ifndef _LIBCPP_NO_EXCEPTIONS + _ForwardIterator __s = __r; + try + { +#endif + for (; __f != __l; ++__f, ++__r) + ::new(&*__r) value_type(*__f); +#ifndef _LIBCPP_NO_EXCEPTIONS + } + catch (...) + { + for (; __s != __r; ++__s) + __s->~value_type(); + throw; + } +#endif return __r; } @@ -3228,12 +3239,23 @@ _ForwardIterator uninitialized_copy_n(_InputIterator __f, _Size __n, _ForwardIterator __r) { - __destruct_n __d(0); typedef typename iterator_traits<_ForwardIterator>::value_type value_type; - unique_ptr<value_type, __destruct_n&> __h(&*__r, __d); - for (; __n > 0; ++__f, ++__r, __d.__incr((value_type*)0), --__n) - ::new(&*__r) value_type(*__f); - __h.release(); +#ifndef _LIBCPP_NO_EXCEPTIONS + _ForwardIterator __s = __r; + try + { +#endif + for (; __n > 0; ++__f, ++__r, --__n) + ::new(&*__r) value_type(*__f); +#ifndef _LIBCPP_NO_EXCEPTIONS + } + catch (...) + { + for (; __s != __r; ++__s) + __s->~value_type(); + throw; + } +#endif return __r; } @@ -3241,24 +3263,46 @@ void uninitialized_fill(_ForwardIterator __f, _ForwardIterator __l, const _Tp& __x) { - __destruct_n __d(0); typedef typename iterator_traits<_ForwardIterator>::value_type value_type; - unique_ptr<value_type, __destruct_n&> __h(&*__f, __d); - for (; __f != __l; ++__f, __d.__incr((value_type*)0)) - ::new(&*__f) value_type(__x); - __h.release(); +#ifndef _LIBCPP_NO_EXCEPTIONS + _ForwardIterator __s = __f; + try + { +#endif + for (; __f != __l; ++__f) + ::new(&*__f) value_type(__x); +#ifndef _LIBCPP_NO_EXCEPTIONS + } + catch (...) + { + for (; __s != __f; ++__s) + __s->~value_type(); + throw; + } +#endif } template <class _ForwardIterator, class _Size, class _Tp> _ForwardIterator uninitialized_fill_n(_ForwardIterator __f, _Size __n, const _Tp& __x) { - __destruct_n __d(0); typedef typename iterator_traits<_ForwardIterator>::value_type value_type; - unique_ptr<value_type, __destruct_n&> __h(&*__f, __d); - for (; __n > 0; ++__f, --__n, __d.__incr((value_type*)0)) - ::new(&*__f) value_type(__x); - __h.release(); +#ifndef _LIBCPP_NO_EXCEPTIONS + _ForwardIterator __s = __f; + try + { +#endif + for (; __n > 0; ++__f, --__n) + ::new(&*__f) value_type(__x); +#ifndef _LIBCPP_NO_EXCEPTIONS + } + catch (...) + { + for (; __s != __f; ++__s) + __s->~value_type(); + throw; + } +#endif return __f; }